/**
 * @package Infinity-Seed
 * @subpackage save
 *
 * @copyright Copyright (C) 2012-2013 Exia.CESI
 * @author Paul MAGNIN, Arthur MERCIER, Jordan RICHET, Cyril SCHUMACHER
 */
package save.format;

import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import save.ISave;

/**
 * Gestion de sauvegarde pour une base de données.
 * @author Jordan RICHET <jordan.richet at viacesi.fr>
 */
public class SaveDatabase implements ISave {
    // <editor-fold defaultstate="collapsed" desc="Attributs.">
    /**
     * Connexion à la base de données.
     */
    private Connection _connection;
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Méthodes.">
    // <editor-fold defaultstate="collapsed" desc="Constructeur.">
    /**
     * Constructeur.
     */
    public SaveDatabase() {
        // Récupère la configuration.
        infinity.seed.Configuration config = infinity.seed.Configuration.getInstance();
        
        // Récupère les identifiants.
        String url = config.get("database.url");
        String user = config.get("database.user");
        String password = config.get("database.password");

        try {
            // Se connecte à la base de données.
            Class.forName(config.get("database.driver"));
            _connection = DriverManager.getConnection(url, user, password);
        } catch (SQLException | ClassNotFoundException e) {
            Logger.getLogger(SaveDatabase.class.getName()).log(Level.SEVERE, null, e);
        }
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Destructeur.">
    /**
     * Destructeur.
     * @throws Throwable 
     */
    @Override public void finalize() throws Throwable {
        super.finalize();
        this._connection.close();
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Créer une sauvegarde de la grille.">
    /**
     * Créer une sauvegarde de la grille.
     * @param size Taille de la grille.
     * @param stepNumber Nombre de pas.
     * @param timeNumber Temps entre chaque pas.
     * @param grid Grille.
     * @return Boolean Retourne TRUE si la grille a ete sauvegardee, FALSE sinon.
     */
    @Override public Boolean setGrid(java.awt.Dimension size, int stepNumber, int timeNumber, String grid) {

        try {
            try (PreparedStatement queryDelete = this._connection.prepareStatement("DELETE FROM SaveTable")) {
                queryDelete.executeUpdate();
            }
            
            // Ajout de la sauvegarde dans la base de données.
            String queryInsert = "INSERT INTO `infinityseed`.`savetable` (`width`, `height`, `nbStep`, `timeBewteenStep`, `grid`) " + " VALUES(?,?,?,?,?)";
            try (PreparedStatement queryAdd = this._connection.prepareStatement(queryInsert)) {
                queryAdd.setDouble(1, size.getWidth());
                queryAdd.setDouble(2, size.getHeight());
                queryAdd.setInt(3, stepNumber);
                queryAdd.setInt(4, timeNumber);
                queryAdd.setString(5, grid);
                queryAdd.executeUpdate();
            }
        } 
        catch (Exception e) 
        {
            // Enregistre l'exception.
            Logger.getLogger(SaveDatabase.class.getName()).log(Level.WARNING, null, e);
            return false;
        }
        
        return true;
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Récupère la largeur du tableau en sauvegarde.">
    /**
     * Récupère la largeur du tableau en sauvegarde.
     * @return Retourne la chaîne de caractère représentant la grille.
     */
    @Override public int getWidth() {
        // Valeur par défaut.
        int witdh = 0;
        try 
        {          
            // Récupère le champs "width" contenu dans la base de données.
            Statement stmt = _connection.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT width FROM SaveTable");
            
            // Récupère le dernier enregistrement.
            while(rs.next())
            {
                witdh = rs.getInt("width");
            }
        } 
        catch (Exception e) 
        {
            // Enregistre l'exception.
            Logger.getLogger(SaveDatabase.class.getName()).log(Level.WARNING, null, e);
        }
        return witdh;
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Récupère la hauteur du tableau en sauvegarde.">
    /**
     * Récupère la hauteur du tableau en sauvegarde.
     * @return Retourne la chaîne de caractère représentant la grille.
     */    
     public int getHeight() {
        int height = 0;
        try 
        {          
            Statement stmt = _connection.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT height FROM SaveTable");
            while(rs.next())
            {
                height = rs.getInt("height");
            }
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
        return height;
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Récupère le nombre de pas.">
    /**
     * Récupère le nombre de pas.
     * @return Retourne la chaîne de caractère représentant la grille.
     */    
     public int getNbStep() {
        int nbStep = 0;
        try 
        {
                        
            Statement stmt = _connection.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT nbStep FROM SaveTable");
            while(rs.next())
            {
                nbStep = rs.getInt("nbStep");
            }
        } 
        catch (Exception e) 
        {
            // Enregistre l'exception.
            Logger.getLogger(SaveDatabase.class.getName()).log(Level.WARNING, null, e);
        }
        return nbStep;
    }
    // </editor-fold>   
    // <editor-fold defaultstate="collapsed" desc="Récupère le temps entre les pas de la sauvegarde.">
    /**
     * Récupère le temps entre les pas de la sauvegarde.
     * @return Retourne la chaine de caractere representant la grille.
     */    
     public int getTimeBetweenStep() {
        int timeBetweenStep = 0;
        try 
        {
                        
            Statement stmt = _connection.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT timeBetweenStep FROM SaveTable");
            while(rs.next())
            {
                timeBetweenStep = rs.getInt("timeBetweenStep");
            }
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
        return timeBetweenStep;
    }
    // </editor-fold> 
    // <editor-fold defaultstate="collapsed" desc="Récupère la sauvegarde.">
    /**
     * Récupère la sauvegarde.
     * @return Retourne la chaîne de caractère représentant la grille.
     */
    @Override public String getGrid() {
        String grid = null;
        try 
        {
                        
            Statement stmt = _connection.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT grid FROM SaveTable");
            while(rs.next())
            {
                grid = rs.getString("grid");
            }
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
        return grid;
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Détermine si une sauvegarde existe.">
    /**
     * Détermine si une sauvegarde existe.
     * @return Retourne TRUE si une sauvegarde existe, FALSE sinon.
     */
    @Override public Boolean exists()
    {
        try 
        { 
            // Récupére le champs "idSaveTable" contenu dans la base de données.
            Statement stmt = _connection.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT idSaveTable FROM SaveTable");
            
            // Retourne TRUE si un enregistrement existe, FALSE si aucun enregistrement.
            return rs.first();           
        } 
        catch (SQLException e) 
        {
            return false;
        }    
    }
    // </editor-fold>
    // </editor-fold>
}